﻿using LBSoft.Business;
using LBSoft.Common.DotNetBean;
using LBSoft.Common.DotNetExt;
using LBSoft.Common.DotNetJson;
using Newtonsoft.Json;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;

namespace LBSoft.HplusAdmin.Business.Common
{
    /// <summary>
    /// UploadifyHandler 的摘要说明
    /// </summary>
    public class UploadifyHandler : IHttpHandler
    {
        HttpContext con;
        mJsonResult json = new mJsonResult();
        Common_Dal systemidao = new Common_Dal();

        public void ProcessRequest(HttpContext context)
        {
            con = context;
            switch (con.Request["PostType"])
            {
                case "upload": Upload(); break; //通用上传方法
                case "uploadPerson": UploadPerson(); break; //人员信息导入
                case "savePerson": SavePerson(); break; //人员信息保存
            }
        }

        /// <summary>
        /// 通用上传方法
        /// </summary>
        private void Upload()
        {
            string dirName = DateTime.Now.ToString("yyyyMMdd");
            string recordType = con.Request["RecordType"].ToString2();

            HttpPostedFile file = con.Request.Files[0];
            string folderName = $"/upfiles/{dirName}/";
            if (!string.IsNullOrEmpty(recordType))
            {
                folderName += $"{recordType}/";
            }
            string uploadPath = HttpContext.Current.Server.MapPath(folderName);

            if (!IsAllowedExtension(file))
            {
                con.Response.Write("检测到上传文件有问题，非法文件名后缀!");
                return;
            }

            if (file != null)
            {
                if (!Directory.Exists(uploadPath))
                {
                    Directory.CreateDirectory(uploadPath);
                }
                string fileExt = Path.GetExtension(file.FileName).ToLower();
                string newFileName = Guid.NewGuid().ToString() + fileExt;
                file.SaveAs(uploadPath + newFileName);
                Dictionary<string, object> dic = new Dictionary<string, object>();
                string filePath = folderName + newFileName;

                dic.Add("AllAnnexPath", GetDomain() + filePath);
                dic.Add("AnnexPath", filePath);
                dic.Add("NewAnnexName", newFileName);
                dic.Add("AnnexName", file.FileName);
                dic.Add("AnnexSize", file.ContentLength);
                dic.Add("RecordType", recordType);

                //dic就是返回的Json字符
                con.Response.Write(JsonConvert.SerializeObject(dic));
            }
            else
            {
                con.Response.Write("0");
            }
        }

        /// <summary>
        /// 人员信息导入
        /// </summary>
        private void UploadPerson()
        {
            try
            {
                HttpPostedFile file = con.Request.Files[0];  //获取保存路径
                string uploadPath = HttpContext.Current.Server.MapPath("~\\upfiles\\" + "UploadPersonExcel\\" + DateTime.Now.ToString("yyyyMMdd") + "\\");     //判断文件是否为空
                if (file != null)
                {
                    if (!Directory.Exists(uploadPath))
                    {
                        Directory.CreateDirectory(uploadPath);
                    }

                    string timessStr = DateTime.Now.ToString("yyyyMMddhhffss");
                    string NewFileName = file.FileName.Replace(Path.GetExtension(file.FileName), "-") + timessStr + Path.GetExtension(file.FileName);
                    //Save File
                    file.SaveAs(uploadPath + NewFileName);

                    string fileUrl = uploadPath + NewFileName;
                    string uploadUrl = "/upfiles/" + "UploadPersonExcel/" + DateTime.Now.ToString("yyyyMMdd") + "/" + NewFileName;

                    int trueNum = 0;
                    int falseNum = 0;
                    DataTable trueDt = new DataTable();
                    DataTable falseDt = new DataTable();
                    string resultMsg = string.Empty;
                    bool result = CheckPersonInfo(fileUrl, out resultMsg, out trueNum, out falseNum, out trueDt, out falseDt);
                    if (result)
                    {
                        string errorFileUrl = string.Empty;

                        //生成错误数据Excel
                        if (falseDt != null && falseDt.Rows.Count > 0)
                        {
                            //导出不符合的数据
                            string path = con.Server.MapPath("~\\upfiles\\" + "人员失败信息\\" + DateTime.Now.ToString("yyyyMMdd") + "\\");
                            if (!Directory.Exists(path))
                            {
                                Directory.CreateDirectory(path);
                            }
                            string timess = DateTime.Now.ToString("yyyyMMddHHmmss");
                            string errorFilePath = path + "人员信息" + timess + ".xls";
                            errorFileUrl = "/upfiles/" + "人员失败信息/" + DateTime.Now.ToString("yyyyMMdd") + "/人员信息" + timess + ".xls";
                            GetBackExcelDrop(falseDt, errorFilePath, "人员失败信息", "人员信息", 11);
                        }

                        var objData = new
                        {
                            trueNum = trueNum,
                            falseNum = falseNum,
                            fileName = NewFileName,
                            uploadUrl = uploadUrl,
                            errorFileUrl = errorFileUrl
                        };
                        json.success = true;
                        json.obj = objData;
                    }
                    else
                    {
                        json.msg = resultMsg;
                    }
                }
                else
                {
                    json.msg = "未上传文件";
                }
            }
            catch (Exception ex)
            {
                json.msg = "上传失败：" + ex.Message;
            }
            con.Response.Write(JsonConvert.SerializeObject(json));
        }

        /// <summary>
        /// 人员信息保存
        /// </summary>
        private void SavePerson()
        {
            string uploadUrl = con.Request["UploadUrl"].ToString2();
            string fullPath = HttpContext.Current.Server.MapPath(uploadUrl);

            int trueNum = 0;
            int falseNum = 0;
            DataTable trueDt = new DataTable();
            DataTable falseDt = new DataTable();
            string resultMsg = string.Empty;
            bool result = CheckPersonInfo(fullPath, out resultMsg, out trueNum, out falseNum, out trueDt, out falseDt);

            json.success = true;
            json.msg = "导入成功" + trueDt.Rows.Count + "条";
            if (trueDt != null && trueDt.Rows.Count > 0)
            {
                json.rows = trueDt;
                //人员库
                DataTable dtPerson = systemidao.GetDataTableBySQL(new StringBuilder(string.Format(@"SELECT * FROM dbo.T_Person")));

                StringBuilder updatePersonSql = new StringBuilder();
                StringBuilder insertPersonSql = new StringBuilder();
                StringBuilder insertWorkerSql = new StringBuilder();

                string userAccount = RequestSession.GetSessionUser().UserAccount.ToString2();
                string userId = RequestSession.GetSessionUser().UserId.ToString2();
                string dateNow = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

                foreach (DataRow dr in trueDt.Rows)
                {
                    DataRow[] personArr = dtPerson.Select("IDCard='" + dr["IDCard"] + "'");

                    //又改无增
                    if (personArr != null && personArr.Length > 0)
                    {
                        string perGUID = personArr[0]["GUID"].ToString2();
                        string updateSql = $@"UPDATE dbo.T_Person	
                        SET PersonName='{dr["PersonName"]}',IDCard='{dr["IDCard"]}',PersonSex='{dr["PersonSex"]}',PersonNation='{dr["PersonNation"]}',Address='{dr["Address"]}'
                        ,Organize='{dr["Organize"]}',BeginDate='{dr["BeginDate"]}',EndDate='{dr["EndDate"]}',LinkPhone='{dr["LinkPhone"]}'
                        ,ModifyDate='{dateNow}',ModifyUserId='{userId}',ModifyAccount='{userAccount}'
                        WHERE GUID='{perGUID}'";
                        updatePersonSql.AppendLine(updateSql);
                    }
                    else
                    {
                        string perGUID = Guid.NewGuid().ToString();
                        string insertPSql = $@"INSERT dbo.T_Person
                        (GUID,PersonName,IDCard,PersonSex,PersonNation,Address,Organize,BeginDate,EndDate,LinkPhone,IsDelete,CreateDate,CreateUserId,CreateAccount)
                        VALUES
                        ('{perGUID}','{dr["PersonName"]}','{dr["IDCard"]}','{dr["PersonSex"]}','{dr["PersonNation"]}','{dr["Address"]}'
                        ,'{dr["Organize"]}','{dr["BeginDate"]}','{dr["EndDate"]}','{dr["LinkPhone"]}'
                        ,0,'{dateNow}','{userId}','{userAccount}')";
                        insertPersonSql.AppendLine(insertPSql);
                    }
                }
                systemidao.ExecuteBySql(updatePersonSql);
                systemidao.ExecuteBySql(insertPersonSql);
            }
            con.Response.Write(JsonConvert.SerializeObject(json));
        }

        /// <summary>
        /// 校验人员信息数据
        /// </summary>
        private bool CheckPersonInfo(string fileUrl, out string resultMsg, out int trueNum, out int falseNum, out DataTable trueDt, out DataTable falseDt)
        {
            try
            {
                bool result = true;
                resultMsg = "file-ok";

                DataTable dtTable = new DataTable();
                dtTable.Columns.Add("RowNum", typeof(string));
                dtTable.Columns.Add("PersonName", typeof(string));
                dtTable.Columns.Add("IDCard", typeof(string));
                dtTable.Columns.Add("PersonSex", typeof(string));
                dtTable.Columns.Add("PersonNation", typeof(string));
                dtTable.Columns.Add("Address", typeof(string));
                dtTable.Columns.Add("Organize", typeof(string));
                dtTable.Columns.Add("BeginDate", typeof(string));
                dtTable.Columns.Add("EndDate", typeof(string));
                dtTable.Columns.Add("LinkPhone", typeof(string));
                dtTable.Columns.Add("Remark", typeof(string));

                trueNum = 0;
                falseNum = 0;
                trueDt = dtTable.Clone();
                falseDt = dtTable.Clone();

                DataRow dr = null;

                using (FileStream fs = File.OpenRead(fileUrl))   //打开.xls文件
                {
                    HSSFWorkbook wk = new HSSFWorkbook(fs);   //把xls文件中的数据写入wk中
                    for (int i = 0; i < wk.NumberOfSheets; i++)  //NumberOfSheets是myxls.xls中总共的表数
                    {
                        ISheet sheet = wk.GetSheetAt(i);   //读取当前表数据
                        //if (sheet.LastRowNum > 201)
                        //{
                        //    //导入模板格式有错误
                        //    con.Response.Write("导入数据不可大于200条");
                        //    return;
                        //}
                        if (sheet.LastRowNum > 0)//行数
                        {
                            IRow headerRow = sheet.GetRow(0);
                            int lastCellNum = headerRow.LastCellNum;
                            //if (lastCellNum != 9) //校验行列数
                            //{
                            //    result = false;
                            //    resultMsg = "导入模板格式不正确";
                            //    return result;
                            //}

                            for (int j = 1; j <= sheet.LastRowNum; j++)  //LastRowNum 是当前表的总行数，j从第二行开始为导入数据
                            {
                                IRow row = sheet.GetRow(j);  //读取当前行数据
                                if (row != null)
                                {
                                    #region 行赋值
                                    string sortNum = row.GetCell(0).ToString2().Trim();
                                    string personName = row.GetCell(1).ToString2().Trim();
                                    string idCard = row.GetCell(2).ToString2().Trim();
                                    string personSex = row.GetCell(3).ToString2().Trim();
                                    string personNation = row.GetCell(4).ToString2().Trim();
                                    string address = row.GetCell(5).ToString2().Trim();
                                    string organize = row.GetCell(6).ToString2().Trim();
                                    string beginDate = row.GetCell(7).ToString2().Trim();
                                    string endDate = row.GetCell(8).ToString2().Trim();
                                    string linkPhone = row.GetCell(9).ToString2().Trim();

                                    DataRow drRow = dtTable.NewRow();
                                    drRow[0] = sortNum;
                                    drRow[1] = personName;
                                    drRow[2] = idCard;
                                    drRow[3] = personSex;
                                    drRow[4] = personNation;
                                    drRow[5] = address;
                                    drRow[6] = organize;
                                    drRow[7] = beginDate;
                                    drRow[8] = endDate;
                                    drRow[9] = linkPhone;
                                    #endregion

                                    //sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限
                                    if (personName != "" && idCard != "" && personSex != ""
                                        && personNation != "" && address != "" && organize != ""
                                        && beginDate != "" && endDate != "" && linkPhone != "")
                                    {
                                        trueNum++;
                                        dr = trueDt.NewRow();
                                        dr.ItemArray = (object[])drRow.ItemArray.Clone();
                                        dr[10] = "导入成功";
                                        trueDt.Rows.Add(dr);
                                    }
                                    else
                                    {
                                        falseNum++;
                                        dr = falseDt.NewRow();
                                        dr.ItemArray = (object[])drRow.ItemArray.Clone();
                                        dr[10] = "信息填写不完整";
                                        falseDt.Rows.Add(dr);
                                    }
                                }
                            }
                        }
                        else if (sheet.LastRowNum == 0)
                        {
                            result = false;
                            resultMsg = "请在模板中填写内容";
                        }
                        else
                        {
                            result = false;
                            resultMsg = "导入模板格式有错误";
                        }
                    }
                }
                return result;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        /// <summary>
        /// 生成错误数据excel
        /// </summary>
        private void GetBackExcelDrop(DataTable dtleadout, string filePath, string sheetName, string exportType, int cellNum)
        {
            HSSFWorkbook hssfworkbook = new HSSFWorkbook();
            ISheet sheet1 = hssfworkbook.CreateSheet(sheetName);
            //内容公共样式
            ICellStyle style = hssfworkbook.CreateCellStyle();
            //自动换行
            style.WrapText = true;
            //设置单元格的样式：水平对齐居中
            style.Alignment = HorizontalAlignment.Center;
            //设置单元格的样式：垂直居中
            style.VerticalAlignment = VerticalAlignment.Center;
            //设置单元格样式为文本格式
            style.DataFormat = HSSFDataFormat.GetBuiltinFormat("@");
            try
            {
                //表头
                IRow row0 = sheet1.CreateRow(0);
                row0.HeightInPoints = 30;
                if (exportType == "人员信息")
                {
                    ICell cell0 = row0.CreateCell(0, CellType.String);
                    cell0.SetCellValue("序号");
                    cell0.CellStyle = style;
                    ICell cell1 = row0.CreateCell(1, CellType.String);
                    cell1.SetCellValue("姓名");
                    cell1.CellStyle = style;
                    ICell cell2 = row0.CreateCell(2, CellType.String);
                    cell2.SetCellValue("身份证号");
                    cell2.CellStyle = style;
                    ICell cell3 = row0.CreateCell(3, CellType.String);
                    cell3.SetCellValue("性别");
                    cell3.CellStyle = style;
                    ICell cell4 = row0.CreateCell(4, CellType.String);
                    cell4.SetCellValue("民族");
                    cell4.CellStyle = style;
                    ICell cell5 = row0.CreateCell(5, CellType.String);
                    cell5.SetCellValue("住址");
                    cell5.CellStyle = style;
                    ICell cell6 = row0.CreateCell(6, CellType.String);
                    cell6.SetCellValue("签发机关");
                    cell6.CellStyle = style;
                    ICell cell7 = row0.CreateCell(7, CellType.String);
                    cell7.SetCellValue("有效期限开始");
                    cell7.CellStyle = style;
                    ICell cell8 = row0.CreateCell(8, CellType.String);
                    cell8.SetCellValue("有效期限结束");
                    cell8.CellStyle = style;
                    ICell cell9 = row0.CreateCell(9, CellType.String);
                    cell9.SetCellValue("联系电话");
                    cell9.CellStyle = style;
                    ICell cell10 = row0.CreateCell(10, CellType.String);
                    cell10.SetCellValue("备注");
                    cell10.CellStyle = style;
                }

                sheet1.SetColumnWidth(0, 8 * 256);

                for (int i = 1; i < cellNum; i++)
                {
                    sheet1.SetColumnWidth(i, 25 * 256);//列宽
                }

                for (int i = 0; i < dtleadout.Rows.Count; i++)
                {
                    IRow rowcontent = sheet1.CreateRow(i + 1);
                    rowcontent.HeightInPoints = 28;
                    for (int j = 0; j < dtleadout.Columns.Count; j++)
                    {
                        ICell celldt = rowcontent.CreateCell(rowcontent.Cells.Count, CellType.String);
                        celldt.SetCellValue(dtleadout.Rows[i][j].ToString2());
                        celldt.CellStyle = style;
                    }
                }

                using (Stream stream = File.OpenWrite(filePath))
                {
                    hssfworkbook.Write(stream);
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        /// <summary>
        /// 获取当前域名及端口
        /// </summary>
        /// <returns></returns>
        public string GetDomain()
        {
            string Domain = HttpContext.Current.Request.Url.AbsoluteUri;
            Domain = Domain.Substring(Domain.IndexOf(":") + 3);//http://之后的
            Domain = Domain.Substring(0, Domain.IndexOf('/'));
            if (HttpContext.Current.Request.Url.AbsoluteUri.StartsWith("https"))
            {
                return "https://" + Domain;
            }
            else
            {
                return "http://" + Domain;
            }
        }

        /// <summary>
        /// 判断文件是否正常，防止伪造文件上传
        /// </summary>
        /// <param name="hifile"></param>
        /// <returns></returns>
        private static bool IsAllowedExtension(HttpPostedFile postedFile)
        {
            int fileLen = postedFile.ContentLength;
            byte[] imgArray = new byte[fileLen];
            postedFile.InputStream.Read(imgArray, 0, fileLen);
            System.IO.MemoryStream fs = new System.IO.MemoryStream(imgArray);
            System.IO.BinaryReader r = new System.IO.BinaryReader(fs);

            string fileclass = "";
            byte buffer;
            try
            {
                buffer = r.ReadByte();
                fileclass = buffer.ToString();
                buffer = r.ReadByte();
                fileclass += buffer.ToString();
            }
            catch
            {
                return false;
            }
            r.Close();
            fs.Close();

            /*文件扩展名说明 
            jpg：255216 
            bmp：6677 
            png：13780
            gif：7173 
            xls,doc,ppt：208207 
            rar：8297 
            zip：8075 
            txt：98109 
            pdf：3780 
            */
            bool ret = false;
            String[] fileType = {
            "255216",
            "6677",
            "13780",
            "7173",
            "208207",
            "8297",
            "8075",
            "98109",
            "3780"
            };
            for (int i = 0; i < fileType.Length; i++)
            {
                if (fileclass == fileType[i])
                {
                    ret = true;
                    break;
                }
            }
            return ret;
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}